#ifndef __G_INPUT_MANAGER_H__
#define __G_INPUT_MANAGER_H__

#include <vector>
#include <unordered_map>

#include "GTypes.h"
#include "GInput.h"
#include "GSingleton.h"
#include "GInitializable.h"

namespace GEngine
{
	//! 1) Keeps Modules
	//! 2) Updates Modules
	//! 3) Keeps all devices in seperate arrays
	//! 4) Functionality for checking device states
	//! 5) For keyboard and mouse keep a single device.
	//! 6) Multiple keyboards and mouses will modify same device instance state
	//! 7) Stores active input maps
	//! 8) Updates input maps after module updates
	
	class GInputModule;
	class GInputDevice;

	class GInputManager : public GUtil::GInitializable, public GUtil::GSingleton<GInputManager>
	{
	friend class GInputModule;
	friend class GUtil::GSingleton<GInputManager>;

	typedef std::unordered_map<std::string, GInputDevice*> DeviceMap;
	typedef std::unordered_map<std::string, GInputModule*> ModuleMap;

	private:
		DeviceMap			InputDevices;
		ModuleMap			InputModules;

							GInputManager();
							~GInputManager();

		void				RegisterDevice(const char* Name, GInputDevice* Device);
		void				UnregisterDevice(const char* Name);

	public:
		GInputModule*		GetModule(const char* ModuleName) const;
		GInputDevice*		GetDevice(const char* DeviceName) const;

		bool				Update(float ElapsedTime);

		virtual bool		Initialize() OVERRIDE;
		virtual bool		InitializeLate() OVERRIDE;

		virtual void		Uninitialize() OVERRIDE;
		virtual void		UninitializeEarly() OVERRIDE;
	};
}

#define mGInputManager		GEngine::GInputManager::GetInstance()

#endif